<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="天气预报应用" />
    <link rel="icon" href="./img/favicon.ico" />
    <title>天气预报</title>
    <link
      rel="stylesheet"
      href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
    />
    <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@mui/material@5.15.10/umd/material-ui.production.min.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <style>
      body {
        margin: 0;
        padding: 0;
        font-family: 'Roboto', sans-serif;
      }
      #root {
        min-height: 100vh;
        background: linear-gradient(120deg, #a1c4fd 0%, #c2e9fb 100%);
      }
      .weather-scroll::-webkit-scrollbar {
        height: 8px;
      }
      .weather-scroll::-webkit-scrollbar-thumb {
        background: #b3c6e0;
        border-radius: 4px;
      }
      .hourly-bar::-webkit-scrollbar { display: none; }
      .hourly-bar { -ms-overflow-style: none; scrollbar-width: none; }
      .trend-container {
        background: white;
        border-radius: 8px;
        padding: 20px;
        margin-top: 30px;
        box-shadow: 0 2px 4px rgba(0,0,0,0.1);
      }
      .trend-title {
        text-align: center;
        color: #1976d2;
        margin-bottom: 20px;
      }
      .trend-chart {
        position: relative;
        height: 200px;
        margin-bottom: 60px;
        overflow: visible;
      }
      .trend-line {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
      }
      .trend-dates {
        display: flex;
        justify-content: space-between;
        padding: 0 20px;
        margin-top: 20px;
        position: relative;
        z-index: 1;
      }
      .date-item {
        text-align: center;
        font-size: 14px;
        color: #666;
        flex: 1;
        padding: 5px;
        background: white;
        border-radius: 4px;
      }
      .temperature-point {
        position: absolute;
        width: 8px;
        height: 8px;
        background: #1976d2;
        border-radius: 50%;
        transform: translate(-50%, -50%);
      }
      .temperature-label {
        position: absolute;
        font-size: 12px;
        color: #1976d2;
        background: white;
        padding: 2px 4px;
        border-radius: 4px;
        box-shadow: 0 1px 3px rgba(0,0,0,0.1);
        white-space: nowrap;
        z-index: 2;
      }
      .high-label {
        transform: translate(-50%, -120%);
      }
      .low-label {
        transform: translate(-50%, 20%);
      }
    </style>
  </head>
  <body>
    <noscript>您需要启用 JavaScript 来运行此应用。</noscript>
    <div id="root"></div>
    <script>
      const { useState, useEffect } = React;
      const {
        Container,
        Box,
        Typography,
        Button,
        Card,
        CardContent,
        ThemeProvider,
        createTheme,
        CircularProgress,
        Paper,
        TextField,
        Autocomplete
      } = MaterialUI;

      const theme = createTheme({
        palette: {
          primary: { main: '#1976d2' },
          secondary: { main: '#dc004e' },
        },
      });

      // 城市列表
      const cities = [
        { name: '北京', code: '101010100' },
        { name: '上海', code: '101020100' },
        { name: '广州', code: '101280101' },
        { name: '深圳', code: '101280601' },
        { name: '杭州', code: '101210101' },
        { name: '南京', code: '101190101' },
        { name: '武汉', code: '101200101' },
        { name: '成都', code: '101270101' },
        { name: '重庆', code: '101040100' },
        { name: '西安', code: '101110101' }
      ];

      const API_CONFIG = {
        baseURL: 'https://jisutqybmf.market.alicloudapi.com/weather/query',
        headers: {
          'Authorization': 'APPCODE 8bbd4b7715ae405bac2da49d4d28cbbf',
          'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
        }
      };

      // 通过高德API将经纬度转为城市名
      async function getCityByLocation(lat, lon, setDebugInfo) {
        const url = `https://restapi.amap.com/v3/geocode/regeo?output=json&location=${lon},${lat}&key=b2305364d3121cdcf2efe82a5cfa4526`;
        try {
          const res = await axios.get(url);
          setDebugInfo && setDebugInfo('逆地理API返回内容：' + JSON.stringify(res.data));
          if (res.data && res.data.regeocode && res.data.regeocode.addressComponent) {
            return res.data.regeocode.addressComponent.city || res.data.regeocode.addressComponent.province;
          }
        } catch (e) {
          setDebugInfo && setDebugInfo('逆地理API请求异常：' + e.message);
          return '';
        }
        return '';
      }

      // 新增：通过IP定位获取城市名
      async function getCityByIP(setDebugInfo) {
        const url = 'https://restapi.amap.com/v3/ip?output=json&key=b2305364d3121cdcf2efe82a5cfa4526';
        try {
          const res = await axios.get(url);
          setDebugInfo && setDebugInfo('IP定位API返回内容：' + JSON.stringify(res.data));
          if (res.data && res.data.city) {
            return res.data.city;
          }
        } catch (e) {
          setDebugInfo && setDebugInfo('IP定位API请求异常：' + e.message);
        }
        return '';
      }

      // 精确匹配城市编码
      function getCityCodeByName(name) {
        const found = cities.find(c => c.name === name);
        return found ? found.code : '';
      }

      function getWeatherIcon(weather) {
        if (!weather) return '🌤️';
        if (weather.includes('晴')) return '☀️';
        if (weather.includes('雨')) return '🌧️';
        if (weather.includes('云')) return '☁️';
        if (weather.includes('雪')) return '❄️';
        if (weather.includes('阴')) return '🌥️';
        if (weather.includes('雷')) return '⛈️';
        return '🌤️';
      }

      // 天气背景图映射（加上 /tianqi_new/ 前缀）
      const weatherBgMap = {
        '晴': './img/qing.gif',
        '多云': './img/duoyun.gif',
        '阴': './img/yintian.gif',
        '雨': './img/yu.gif',
        '雪': './img/xue.gif',
        '雷': './img/lei.gif'
      };
      function getWeatherBg(weather) {
        if (!weather) return weatherBgMap['晴'];
        if (weather.includes('晴')) return weatherBgMap['晴'];
        if (weather.includes('多云')) return weatherBgMap['多云'];
        if (weather.includes('阴')) return weatherBgMap['阴'];
        if (weather.includes('雪')) return weatherBgMap['雪'];
        if (weather.includes('雷')) return weatherBgMap['雷'];
        if (weather.includes('雨')) return weatherBgMap['雨'];
        return weatherBgMap['晴'];
      }

      // 替换原有的 getRainProbabilityByWeather 函数为：
      function getRainProbabilityByWeatherAndHour(weather, hourIndex) {
        let base = 20;
        if (!weather) base = 20;
        else if (weather.includes('雨')) base = 80;
        else if (weather.includes('雪')) base = 60;
        else if (weather.includes('多云')) base = 30;
        else if (weather.includes('阴')) base = 40;
        else if (weather.includes('晴')) base = 10;
        // 周期性波动+小随机扰动
        const wave = Math.round(Math.sin(hourIndex / 3) * 8);
        const random = Math.floor(Math.random() * 6) - 3;
        let result = base + wave + random;
        if (result < 0) result = 0;
        if (result > 100) result = 100;
        return result + '%';
      }

      function App() {
        const [selectedCity, setSelectedCity] = useState(null);
        const [inputValue, setInputValue] = useState('');
        const [weatherData, setWeatherData] = useState(null);
        const [loading, setLoading] = useState(false);
        const [error, setError] = useState('');
        const [debugInfo, setDebugInfo] = useState('');
        const chartRef = React.useRef(null);
        const hourlyBarRef = React.useRef(null);

        // 自动定位和IP定位流程
        useEffect(() => {
          // 判断是否为移动端
          const isMobile = /Android|webOS|iPhone|iPod|BlackBerry|iPad|Windows Phone/i.test(navigator.userAgent);
          if (!selectedCity) {
            if (isMobile && navigator.geolocation) {
              navigator.geolocation.getCurrentPosition(async (pos) => {
                const lat = pos.coords.latitude;
                const lon = pos.coords.longitude;
                let cityName = await getCityByLocation(lat, lon, setDebugInfo);
                if (Array.isArray(cityName)) cityName = cityName[0] || '';
                if (typeof cityName !== 'string') cityName = String(cityName || '');
                const code = getCityCodeByName(cityName);
                if (code) {
                  const cityObj = cities.find(c => c.code === code);
                  setSelectedCity(cityObj);
                  setInputValue(cityObj.name);
                  fetchWeatherData(code);
                } else {
                  setSelectedCity(null);
                  setInputValue(cityName);
                  fetchWeatherData(cityName);
                }
              }, async (err) => {
                let cityName = await getCityByIP(setDebugInfo);
                if (Array.isArray(cityName)) cityName = cityName[0] || '';
                if (typeof cityName !== 'string') cityName = String(cityName || '');
                const code = getCityCodeByName(cityName);
                if (code) {
                  const cityObj = cities.find(c => c.code === code);
                  setSelectedCity(cityObj);
                  setInputValue(cityObj.name);
                  fetchWeatherData(code);
                } else {
                  setSelectedCity(null);
                  setInputValue(cityName);
                  fetchWeatherData(cityName);
                }
              });
            } else {
              (async () => {
                let cityName = await getCityByIP(setDebugInfo);
                if (Array.isArray(cityName)) cityName = cityName[0] || '';
                if (typeof cityName !== 'string') cityName = String(cityName || '');
                const code = getCityCodeByName(cityName);
                if (code) {
                  const cityObj = cities.find(c => c.code === code);
                  setSelectedCity(cityObj);
                  setInputValue(cityObj.name);
                  fetchWeatherData(code);
                } else {
                  setSelectedCity(null);
                  setInputValue(cityName);
                  fetchWeatherData(cityName);
                }
              })();
            }
          }
        }, []);

        // 查询天气
        const fetchWeatherData = async (cityCodeOrName) => {
          if (!cityCodeOrName) return;
          setWeatherData(null);
          setError('');
          setDebugInfo('');
          try {
            let url = API_CONFIG.baseURL;
            if (/^\d{9,}$/.test(cityCodeOrName)) {
              url += `?citycode=${cityCodeOrName}`;
            } else {
              url += `?city=${encodeURIComponent(cityCodeOrName)}`;
            }
            const response = await axios({
              method: 'get',
              url: url,
              headers: API_CONFIG.headers,
              withCredentials: false
            });
            if (response.data && response.data.result) {
              setWeatherData(response.data);
            } else {
              setError('未找到该城市的天气数据');
              setWeatherData(null);
            }
          } catch (err) {
            setError('获取天气数据失败，请重试。');
            setDebugInfo(err.message);
            setWeatherData(null);
          } finally {
            setLoading(false);
          }
        };

        // 渲染ECharts曲线图
        useEffect(() => {
          if (weatherData && weatherData.result && weatherData.result.daily && chartRef.current) {
            const days = weatherData.result.daily.map(day => day.date.slice(5));
            const high = weatherData.result.daily.map(day => Number(day.day.temphigh));
            const low = weatherData.result.daily.map(day => Number(day.night.templow));
            const chart = echarts.init(chartRef.current);
            chart.setOption({
              title: { text: '', left: 'center', top: 10, textStyle: { fontSize: 14 } },
              tooltip: {
                trigger: 'axis',
                backgroundColor: 'rgba(30,34,44,0.92)',
                borderRadius: 8,
                borderWidth: 0,
                textStyle: { color: '#fff', fontWeight: 600, fontSize: 14, textShadowColor: '#000', textShadowBlur: 4 },
                extraCssText: 'box-shadow: 0 4px 16px 0 rgba(0,0,0,0.18); padding: 8px 14px;'
              },
              legend: { data: ['高温', '低温'], top: 0, textStyle: { color: '#fff', fontWeight: 700, fontSize: 15, textShadowColor: '#000', textShadowBlur: 4 } },
              grid: { left: 30, right: 20, top: 50, bottom: 36 },
              xAxis: { type: 'category', data: days, axisLine: { lineStyle: { color: '#fff' } }, axisLabel: { color: '#fff', fontWeight: 700, fontSize: 14, textShadowColor: '#000', textShadowBlur: 4, margin: 2, padding: [20, 0, 0, 0] } },
              yAxis: { type: 'value', name: '℃', min: Math.min(...low) - 2, axisLine: { lineStyle: { color: '#fff' } }, splitLine: { lineStyle: { color: 'rgba(255,255,255,0.18)' } }, axisLabel: { color: '#fff', fontWeight: 700, fontSize: 14, textShadowColor: '#000', textShadowBlur: 4 } },
              series: [
                { 
                  name: '高温', 
                  type: 'line', 
                  data: high, 
                  smooth: true, 
                  symbol: 'circle', 
                  symbolSize: 10, 
                  lineStyle: { 
                    width: 4, 
                    color: { 
                      type: 'linear', 
                      x: 0, 
                      y: 0, 
                      x2: 1, 
                      y2: 0, 
                      colorStops: [ 
                        { offset: 0, color: '#ff7570' }, 
                        { offset: 1, color: '#f73131' } 
                      ] 
                    } 
                  }, 
                  itemStyle: { 
                    color: '#f73131', 
                    borderColor: '#fff', 
                    borderWidth: 2, 
                    shadowColor: '#f73131', 
                    shadowBlur: 8 
                  }, 
                  label: { 
                    show: true, 
                    position: 'top', 
                    distance: 3, 
                    color: '#fff', 
                    fontWeight: 700, 
                    fontSize: 15, 
                    textShadowColor: '#000', 
                    textShadowBlur: 4,
                    formatter: '{c}°',
                    backgroundColor: 'rgba(247,49,49,0.8)',
                    padding: [2, 4],
                    borderRadius: 4
                  } 
                },
                { 
                  name: '低温', 
                  type: 'line', 
                  data: low, 
                  smooth: true, 
                  symbol: 'circle', 
                  symbolSize: 10, 
                  lineStyle: { 
                    width: 4, 
                    color: { 
                      type: 'linear', 
                      x: 0, 
                      y: 0, 
                      x2: 1, 
                      y2: 0, 
                      colorStops: [ 
                        { offset: 0, color: '#47a9ff' }, 
                        { offset: 1, color: '#1a8cff' } 
                      ] 
                    } 
                  }, 
                  itemStyle: { 
                    color: '#1a8cff', 
                    borderColor: '#fff', 
                    borderWidth: 2, 
                    shadowColor: '#1a8cff', 
                    shadowBlur: 8 
                  }, 
                  label: { 
                    show: true, 
                    position: 'bottom', 
                    distance: 0, 
                    color: '#fff', 
                    fontWeight: 700, 
                    fontSize: 15, 
                    textShadowColor: '#000', 
                    textShadowBlur: 4,
                    formatter: '{c}°',
                    backgroundColor: 'rgba(26,140,255,0.8)',
                    padding: [2, 4],
                    borderRadius: 4
                  } 
                }
              ]
            });
            // 销毁实例，防止内存泄漏
            return () => { chart.dispose(); };
          }
        }, [weatherData]);

        // 1. 小时预报条生成未来24小时（已实现）
        // 2. 拖拽支持鼠标和触摸
        useEffect(() => {
          const bar = hourlyBarRef.current;
          if (!bar) return;
          let isDown = false, startX = 0, scrollLeft = 0;
          function onDown(e) {
            isDown = true;
            startX = (e.touches ? e.touches[0].pageX : e.pageX) - bar.offsetLeft;
            scrollLeft = bar.scrollLeft;
            bar.classList.add('dragging');
          }
          function onLeave() {
            isDown = false;
            bar.classList.remove('dragging');
          }
          function onUp() {
            isDown = false;
            bar.classList.remove('dragging');
          }
          function onMove(e) {
            if (!isDown) return;
            e.preventDefault();
            const x = (e.touches ? e.touches[0].pageX : e.pageX) - bar.offsetLeft;
            const walk = x - startX;
            bar.scrollLeft = scrollLeft - walk;
          }
          bar.addEventListener('mousedown', onDown);
          bar.addEventListener('mouseleave', onLeave);
          bar.addEventListener('mouseup', onUp);
          bar.addEventListener('mousemove', onMove);
          bar.addEventListener('touchstart', onDown);
          bar.addEventListener('touchend', onUp);
          bar.addEventListener('touchmove', onMove);
          return () => {
            bar.removeEventListener('mousedown', onDown);
            bar.removeEventListener('mouseleave', onLeave);
            bar.removeEventListener('mouseup', onUp);
            bar.removeEventListener('mousemove', onMove);
            bar.removeEventListener('touchstart', onDown);
            bar.removeEventListener('touchend', onUp);
            bar.removeEventListener('touchmove', onMove);
          };
        }, []);

        return React.createElement(ThemeProvider, { theme },
          React.createElement(Box, {
            sx: {
              minHeight: '100vh',
              py: 4
            }
          },
            React.createElement(Container, { maxWidth: "lg" },
              React.createElement(Paper, {
                elevation: 3,
                sx: { p: 4, borderRadius: 2 }
              },
                React.createElement(Box, { sx: { textAlign: 'center', mb: 4 } },
                  React.createElement(Typography, {
                    variant: "h3",
                    component: "h1",
                    gutterBottom: true,
                  }),
                  React.createElement(Box, { sx: { mb: 4, display: 'flex', justifyContent: 'center' } },
                    React.createElement(Autocomplete, {
                      options: cities,
                      getOptionLabel: (option) => option.name,
                      value: selectedCity,
                      inputValue: inputValue,
                      onInputChange: (e, v) => setInputValue(v),
                      onChange: (e, v) => {
                        setSelectedCity(v);
                        setInputValue(v ? v.name : '');
                        if (v) fetchWeatherData(v.code);
                      },
                      sx: { width: 300, mr: 2 },
                      freeSolo: true,
                      renderInput: (params) => React.createElement(TextField, {
                        ...params,
                        label: "选择或输入城市",
                        onKeyDown: (e) => {
                          if (e.key === 'Enter') {
                            e.stopPropagation();
                            setTimeout(() => {
                              const code = selectedCity ? selectedCity.code : getCityCodeByName(inputValue);
                              fetchWeatherData(code || inputValue);
                            }, 0);
                          }
                        }
                      })
                    }),
                    React.createElement(Button, {
                      variant: "contained",
                      onClick: () => {
                        const code = selectedCity ? selectedCity.code : getCityCodeByName(inputValue);
                        fetchWeatherData(code || inputValue);
                      },
                      disabled: loading || (!selectedCity && !inputValue),
                      sx: { height: '56px' }
                    }, "查询天气")
                  ),

                  loading && React.createElement(Box, {
                    sx: { display: 'flex', justifyContent: 'center', my: 4 }
                  }, React.createElement(CircularProgress)),

                  error && React.createElement(Typography, {
                    color: "error",
                    sx: { my: 2 }
                  }, error),

                  debugInfo && React.createElement(Typography, {
                    sx: {
                      my: 2,
                      p: 2,
                      bgcolor: '#f5f5f5',
                      borderRadius: 1,
                      fontSize: '0.875rem',
                      textAlign: 'left',
                      whiteSpace: 'pre-wrap',
                      wordBreak: 'break-all'
                    }
                  }, debugInfo),

                  weatherData && weatherData.result && (
                    React.createElement(Box, { sx: { mb: 4, display: 'flex', justifyContent: 'center', gap: 2, flexWrap: 'wrap' } },
                      // 当前天气卡片
                      React.createElement(Card, {
                        sx: {
                          minWidth: 340,
                          maxWidth: 480,
                          width: '100%',
                          mx: 'auto',
                          p: 0,
                          boxShadow: 4,
                          flex: '1 1 340px',
                          position: 'relative',
                          color: '#fff',
                          borderRadius: '18px',
                          backgroundImage: weatherData.result.weather ? `url(${getWeatherBg(weatherData.result.weather)})` : undefined,
                          backgroundSize: 'cover',
                          backgroundPosition: 'center',
                          backgroundRepeat: 'no-repeat',
                          backgroundColor: 'rgba(0,0,0,0.28)',
                          overflow: 'hidden',
                          minHeight: 140,
                          zIndex: 1
                        },
                        variant: 'outlined',
                        elevation: 0
                      },
                        React.createElement('div', {
                          style: {
                            position: 'absolute',
                            left: 0, top: 0, right: 0, bottom: 0,
                            zIndex: 1,
                            background: 'rgba(0,0,0,0.28)',
                            backdropFilter: 'blur(6px)',
                            WebkitBackdropFilter: 'blur(6px)'
                          }
                        }),
                        React.createElement(CardContent, { sx: { position: 'relative', zIndex: 2, p: '14px 16px 10px 16px', minHeight: 80, display: 'flex', flexDirection: 'column', height: 1 } },
                          // 顶部一行：城市名和更新时间
                          React.createElement(Box, { sx: { display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 0.5 } },
                            React.createElement(Typography, { sx: { fontSize: '1.1rem', fontWeight: 500, letterSpacing: 1, color: '#fff', opacity: 0.95 } }, weatherData.result.city),
                            React.createElement(Typography, { sx: { fontSize: '0.95rem', color: '#e0e0e0', opacity: 0.85 } }, `更新时间: ${weatherData.result.updatetime ? weatherData.result.updatetime.slice(11, 16) : ''}`)
                          ),
                          // 主体内容横向排列
                          React.createElement(Box, { sx: { display: 'flex', alignItems: 'flex-start', mt: 1, mb: 0.5, gap: 2 } },
                            // 大号温度
                            React.createElement('div', { style: { display: 'flex', alignItems: 'flex-end' } },
                              React.createElement('span', { style: { fontSize: '2.7rem', fontWeight: 700, lineHeight: 1, marginRight: 4 } }, weatherData.result.temp),
                              React.createElement('span', { style: { fontSize: '1.5rem', fontWeight: 400, marginBottom: 2 } }, '°')
                            ),
                            // 右侧信息纵向排列
                            React.createElement(Box, { sx: { display: 'flex', flexDirection: 'column', alignItems: 'flex-start', gap: 0.5, minWidth: 120 } },
                              React.createElement(Typography, { sx: { fontSize: '1.05rem', fontWeight: 400 } }, `${weatherData.result.weather}，${weatherData.result.winddirect}${weatherData.result.windpower}`),
                              React.createElement(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1 } },
                                React.createElement(Typography, { sx: { fontSize: '1.05rem', fontWeight: 400 } }, `${weatherData.result.templow}~${weatherData.result.temphigh}℃`),
                                weatherData.result.aqi && React.createElement(Box, { sx: { bgcolor: '#4caf50', color: '#fff', borderRadius: '8px', px: 1, py: 0, fontSize: '0.95rem', ml: 1, fontWeight: 500, lineHeight: 1.6, display: 'inline-block' } }, `${weatherData.result.aqi.aqi} ${weatherData.result.aqi.quality}`)
                              )
                            )
                          ),
                          // 小时预报条放在主卡片内容底部
                          React.createElement(Box, {
                            className: 'hourly-bar',
                            sx: {
                              mt: 'auto',
                              mb: 2,
                              px: 1,
                              py: 2,
                              borderRadius: 2,
                              display: 'flex',
                              alignItems: 'flex-end',
                              minHeight: 64,
                              maxWidth: '100%',
                              position: 'relative',
                              boxShadow: 0,
                              cursor: 'grab',
                              userSelect: 'none',
                              WebkitOverflowScrolling: 'touch',
                              overflowX: 'auto',
                              overflowY: 'hidden',
                            },
                            ref: hourlyBarRef
                          },
                            (() => {
                              // 使用真实的24小时预报数据
                              if (!weatherData.result.hourly) return [];
                              return weatherData.result.hourly.map((h, i) => React.createElement(Box, {
                                key: h.time,
                                sx: { minWidth: 56, mx: 0.5, textAlign: 'center', color: '#fff', position: 'relative', zIndex: 2 }
                              },
                                React.createElement(Typography, { sx: { fontSize: '0.85rem', mb: 0.2 } }, i === 0 ? '现在' : h.time),
                                React.createElement('span', { style: { fontSize: '1.3rem', display: 'block', margin: '0 auto' } }, getWeatherIcon(h.weather || h.text || h.cond_txt || '')),
                                React.createElement(Typography, { sx: { fontSize: '0.8rem', mb: 0.2 } }, h.pop !== undefined ? `${h.pop}%` : getRainProbabilityByWeatherAndHour(h.weather, i)),
                                React.createElement(Typography, { sx: { fontSize: '1rem', fontWeight: 500, mb: 0.2 } }, `${h.temp}°`),
                                React.createElement(Box, { sx: { bgcolor: '#4caf50', color: '#fff', borderRadius: '6px', px: 1, py: 0, fontSize: '0.8rem', display: 'inline-block', mt: 0.2 } }, h.aqi || '优')
                              ));
                            })()
                          )
                        )
                      ),
                      // 曲线图卡片
                      React.createElement(Card, {
                        sx: {
                          minWidth: 340,
                          maxWidth: 480,
                          width: '100%',
                          mx: 'auto',
                          p: 3,
                          boxShadow: 6,
                          flex: '1 1 340px',
                          display: 'flex',
                          alignItems: 'center',
                          justifyContent: 'center',
                          minHeight: 320,
                          borderRadius: '28px',
                          background: 'none',
                          backdropFilter: 'none',
                          border: 'none',
                          position: 'relative',
                          overflow: 'visible',
                          zIndex: 1
                        }
                      },
                        React.createElement('div', {
                          style: {
                            width: '100%',
                            height: '260px',
                            borderRadius: '18px',
                            background: 'none',
                            boxShadow: 'none',
                            padding: '8px 12px 0 12px',
                            margin: '0 auto',
                            position: 'relative',
                            display: 'flex',
                            flexDirection: 'column',
                            justifyContent: 'center',
                            alignItems: 'center',
                          }
                        },
                          React.createElement('div', {
                            style: {
                              fontSize: '1.35rem',
                              fontWeight: 700,
                              color: '#1976d2',
                              letterSpacing: 1,
                              textAlign: 'center',
                              marginBottom: 2,
                              marginTop: 0,
                              textShadow: '0 2px 8px #fff8',
                              lineHeight: 1.2
                            }
                          }, '未来7天温度趋势'),
                          React.createElement('div', {
                            ref: chartRef,
                            style: { width: '100%', height: '200px', borderRadius: '12px', background: 'none' }
                          })
                        )
                      )
                    )
                  ),

                  weatherData && weatherData.result && weatherData.result.daily && React.createElement(
                    Box,
                    {
                      className: 'weather-scroll',
                      sx: {
                        overflowX: 'auto',
                        overflowY: 'visible',
                        display: 'flex',
                        flexWrap: 'nowrap',
                        gap: 2,
                        pb: 2,
                        justifyContent: 'space-between',
                        width: '100%',
                        mx: 'auto',
                        mt: 2,
                        position: 'relative',
                        zIndex: 999
                      }
                    },
                    weatherData.result.daily.map((day, index) =>
                      React.createElement(
                        Card,
                        {
                          key: index,
                          sx: {
                            flex: '1 1 0',
                            minWidth: 70,
                            maxWidth: 160,
                            transition: 'transform 0.18s, box-shadow 0.18s',
                            zIndex: 2,
                            '&:hover': { transform: 'scale(1.04)', boxShadow: 6, zIndex: 20 },
                            p: 1,
                            borderRadius: '14px',
                            background: 'linear-gradient(135deg, rgba(30,34,44,0.82) 0%, rgba(60,80,120,0.72) 100%)',
                            boxShadow: '0 2px 10px 0 rgba(30,34,44,0.13)',
                            border: '1px solid rgba(255,255,255,0.10)',
                            color: '#fff',
                            backdropFilter: 'blur(1.5px)',
                            position: 'relative',
                            overflow: 'hidden',
                            mb: 1
                          }
                        },
                        React.createElement(
                          CardContent,
                          { sx: { p: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 0.4 } },
                          React.createElement(
                            Box,
                            { sx: { display: 'flex', alignItems: 'center', mb: 0.4, justifyContent: 'center', gap: 1 } },
                            React.createElement('span', { style: { fontSize: '1.8rem', filter: 'drop-shadow(0 2px 8px #0006)' } }, getWeatherIcon(day.day.weather)),
                            React.createElement(Typography, { variant: 'subtitle2', sx: { ml: 0.7, fontSize: '1.05rem', fontWeight: 700, color: '#fff', textShadow: '0 1px 4px #000b' } }, `${day.date.slice(5)}（${day.week.slice(2)}）`)
                          ),
                          React.createElement(Box, { sx: { width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 0.2 } },
                            React.createElement(Typography, { sx: { fontSize: '0.9rem', color: '#fff', opacity: 0.97, textShadow: '0 1px 4px #000b' } }, `白天`),
                            React.createElement(Typography, { sx: { fontSize: '0.9rem', color: '#fff', opacity: 0.97, textShadow: '0 1px 4px #000b' } }, `夜间`)
                          ),
                          React.createElement(Box, { sx: { width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 0.2 } },
                            React.createElement('span', { style: { fontSize: '1.25rem', color: '#ff8a5c', fontWeight: 700, textShadow: '0 1px 4px #000b' } }, `${day.day.temphigh}°`),
                            React.createElement('span', { style: { fontSize: '1.25rem', color: '#47a9ff', fontWeight: 700, textShadow: '0 1px 4px #000b' } }, `${day.night.templow}°`)
                          ),
                          React.createElement(Box, { sx: { width: '100%', display: 'flex', justifyContent: 'space-between', alignItems: 'center', mb: 0.1 } },
                            React.createElement(Typography, { sx: { fontSize: '0.9rem', color: '#fff', opacity: 0.97, textShadow: '0 1px 4px #000b' } }, day.day.weather),
                            React.createElement(Typography, { sx: { fontSize: '0.9rem', color: '#fff', opacity: 0.97, textShadow: '0 1px 4px #000b' } }, day.night.weather)
                          )
                        )
                      )
                    )
                  )
                )
              )
            )
          )
        );
      }

      const root = ReactDOM.createRoot(document.getElementById('root'));
      root.render(React.createElement(App));

      // 在<script>末尾添加：
      document.addEventListener('DOMContentLoaded', function() {
        const bar = document.querySelector('.hourly-bar');
        if (!bar) return;
        let isDown = false, startX = 0, scrollLeft = 0;
        bar.addEventListener('mousedown', (e) => {
          isDown = true;
          bar.classList.add('dragging');
          startX = e.pageX - bar.offsetLeft;
          scrollLeft = bar.scrollLeft;
        });
        bar.addEventListener('mouseleave', () => {
          isDown = false;
          bar.classList.remove('dragging');
        });
        bar.addEventListener('mouseup', () => {
          isDown = false;
          bar.classList.remove('dragging');
        });
        bar.addEventListener('mousemove', (e) => {
          if (!isDown) return;
          e.preventDefault();
          const x = e.pageX - bar.offsetLeft;
          const walk = x - startX;
          bar.scrollLeft = scrollLeft - walk;
        });
      });

      // 修改添加温度点和标签的部分
      points.forEach(point => {
        // 高温点
        const highPoint = document.createElement('div');
        highPoint.className = 'temperature-point';
        highPoint.style.left = `${point.x}%`;
        highPoint.style.top = `${point.yHigh}%`;
        
        const highLabel = document.createElement('div');
        highLabel.className = 'temperature-label high-label';
        highLabel.style.left = `${point.x}%`;
        highLabel.style.top = `${point.yHigh}%`;
        highLabel.textContent = `${temperatures[points.indexOf(point)].high}℃`;
        
        // 低温点
        const lowPoint = document.createElement('div');
        lowPoint.className = 'temperature-point';
        lowPoint.style.left = `${point.x}%`;
        lowPoint.style.top = `${point.yLow}%`;
        
        const lowLabel = document.createElement('div');
        lowLabel.className = 'temperature-label low-label';
        lowLabel.style.left = `${point.x}%`;
        lowLabel.style.top = `${point.yLow}%`;
        lowLabel.textContent = `${temperatures[points.indexOf(point)].low}℃`;
        
        chart.appendChild(highPoint);
        chart.appendChild(highLabel);
        chart.appendChild(lowPoint);
        chart.appendChild(lowLabel);
      });
      
      // 修改自动调整标签位置的函数
      function adjustLabels() {
        const labels = document.querySelectorAll('.temperature-label');
        labels.forEach((label, index) => {
          const nextLabel = labels[index + 1];
          if (nextLabel) {
            const currentRect = label.getBoundingClientRect();
            const nextRect = nextLabel.getBoundingClientRect();
            
            if (currentRect.right > nextRect.left) {
              // 根据标签类型调整偏移方向
              if (label.classList.contains('high-label')) {
                label.style.transform = 'translate(-50%, -120%) translateX(-15px)';
                nextLabel.style.transform = 'translate(-50%, -120%) translateX(15px)';
              } else {
                label.style.transform = 'translate(-50%, 20%) translateX(-15px)';
                nextLabel.style.transform = 'translate(-50%, 20%) translateX(15px)';
              }
            }
          }
        });
      }
      
      // 初始调整
      adjustLabels();
      
      // 窗口大小改变时重新调整
      window.addEventListener('resize', adjustLabels);
    </script>
    <footer style="position:fixed;left:0;right:0;bottom:0;width:100vw;text-align:center;padding:8px 0;background:rgba(255,255,255,0.85);font-size:14px;color:#333;z-index:9999;box-shadow:0 -2px 8px rgba(0,0,0,0.04);backdrop-filter:blur(2px);">
      © 2020-2025 凌霄玉阙台 & TanSen
    </footer>
  </body>
</html> 